Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use XDG_CACHE_HOME. #175

Merged
merged 5 commits into from Jun 27, 2022
Merged

Use XDG_CACHE_HOME. #175

merged 5 commits into from Jun 27, 2022

Conversation

tupo2
Copy link
Contributor

@tupo2 tupo2 commented Jun 21, 2022

Closes #174.

@johanmalm
Copy link
Collaborator

Thanks for doing such a thorough job. I've got a few comments and will do a review to discuss.

@@ -56,9 +56,11 @@ def process_line(line):
setconfig("color_title_border", rgb2hex(line))

def cache(themename):
""" save the theme-name to ~/.cache/jgmenu/.last-gtktheme """
""" save the theme-name to XDG_CACHE_HOME/jgmenu/.last-gtktheme """
from xdg.BaseDirectory import xdg_cache_home
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Importing from xdg crashes for me - I obviously do not have the xdg module installed
In order to avoid creating work for distro maintainers (@johnraff ??) I prefer going manual on this one.
Any chance of manually using XDG_CACHE_HOME if set/non-empty or else use ~/.cache

Traceback (most recent call last):
  File "/home/johan/tmp/jgmenu/./contrib/gtktheme/jgmenu-gtktheme.py", line 106, in <module>
    main()
  File "/home/johan/tmp/jgmenu/./contrib/gtktheme/jgmenu-gtktheme.py", line 74, in main
    cache(themename)
  File "/home/johan/tmp/jgmenu/./contrib/gtktheme/jgmenu-gtktheme.py", line 60, in cache
    from xdg.BaseDirectory import xdg_cache_home
ModuleNotFoundError: No module named 'xdg'

Copy link
Contributor

@johnraff johnraff Jun 22, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

XDG_CACHE_HOME is unset by default in Debian, so a test to only use that envvar if it is set, otherwise reverting to the default $HOME/.cache, would be desirable IMO.

Most of these XDG envvars seem to be unset by default in fact - the user is only expected to set them if they want to use a custom value.

src/cache.c Outdated Show resolved Hide resolved
src/cache.c Outdated
@@ -136,11 +138,18 @@ static void cache_init(void)
die("cache.c: icon_{theme,size} needs to be set");
cache_location = xmalloc(sizeof(struct sbuf));
sbuf_init(cache_location);
sbuf_cpy(cache_location, CACHE_LOCATION);
if (access(xdg_cache_home, F_OK) == 0) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest: #define DEFAULT_CACHE_LOCATION="~/.cache" and then

if (xdg_cache_home && *xdg_cache_home) {
  sbuf_cpy(cache_location, xdg_cache_home)
} else {
  sbuf_cpy(cache_location, DEFAULT_CACHE_LOCATION)
}
sbuf_addstr(cache_location, "jgmenu/icons")
sbuf_expand_tilde.... and so on...

src/icon.c Outdated
@@ -39,6 +38,8 @@ static struct list_head icon_cache;

static struct sbuf icon_theme;

extern struct sbuf *cache_location;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed above, I prefer to remove this extern in favor of a cache_get_dir(). It's just tidier and seems less like using global variables.

@tupo2
Copy link
Contributor Author

tupo2 commented Jun 22, 2022

Thanks for the suggestions, I took them into consideration in a second patch.

@codecov-commenter
Copy link

codecov-commenter commented Jun 24, 2022

Codecov Report

Merging #175 (9c8c9a7) into master (57f5e88) will not change coverage.
The diff coverage is n/a.

@@           Coverage Diff           @@
##           master     #175   +/-   ##
=======================================
  Coverage   38.78%   38.78%           
=======================================
  Files           8        8           
  Lines         856      856           
=======================================
  Hits          332      332           
  Misses        524      524           

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 57f5e88...9c8c9a7. Read the comment docs.

@tupo2
Copy link
Contributor Author

tupo2 commented Jun 24, 2022

Improved the patch.

@johanmalm
Copy link
Collaborator

Thanks. I'll have a look tomorrow if that's okay.

@johanmalm
Copy link
Collaborator

I think we could simplify this even further 😄

I suggest the following (although have not tried putting it into code):

  • Just use cache_location as the one variable that stores the cache_location.
    Set cache_location during cache_init(). Don't bother re-setting it later.
    It's already free'd in cache_atexit_cleanup() so nothing to do there.

That way you can get rid of tmp_cl and tmp_icon_cl and associated cache_dir_cleanup()
and also re-write cache_icon_get_dir() to simply this:

char *cache_icon_get_dir(void)
{
	return cache_location.buf;
}

Also, in cache_get_dir() you call access() to check for the existance of
a cache dir (if XDG_CACHE_HOME is set). I'd argue that this is not needed.
If the user has specified an XDG_CACHE_HOME that doesn't exist, we just
mkdir_p() it rather than defaulting to DEFAULT_CACHE_LOCATION.

@johanmalm
Copy link
Collaborator

I'm happy to get rid of the following icon.c lines altogether. I actually think it's excessive logging which might be useful during development, but not for users.

if (nr_symlinks)
		fprintf(stderr, "info: created %d symlinks in %s\n", nr_symlinks, cache_icon_get_dir());

That would simplify things ever more 😃

@tupo2
Copy link
Contributor Author

tupo2 commented Jun 25, 2022

That way you can get rid of tmp_cl and tmp_icon_cl and associated cache_dir_cleanup() and also re-write cache_icon_get_dir() to simply this:

char *cache_icon_get_dir(void)
{
	return cache_location.buf;
}

Good idea, I made some tests and it works fine.

Also, in cache_get_dir() you call access() to check for the existance of a cache dir (if XDG_CACHE_HOME is set). I'd argue that this is not needed. If the user has specified an XDG_CACHE_HOME that doesn't exist, we just mkdir_p() it rather than defaulting to DEFAULT_CACHE_LOCATION.

I don't understand here, because we need to test if XDG_CACHE_HOME is set or not.
And if it is not, use DEFAULT_CACHE_LOCATION.

@tupo2
Copy link
Contributor Author

tupo2 commented Jun 25, 2022

I'm happy to get rid of the following icon.c lines altogether. I actually think it's excessive logging which might be useful during development, but not for users.

if (nr_symlinks)
		fprintf(stderr, "info: created %d symlinks in %s\n", nr_symlinks, cache_icon_get_dir());

That would simplify things ever more smiley

I prefer to keep it in case we forgot something and removes it later.

@johanmalm
Copy link
Collaborator

Also, in cache_get_dir() you call access() to check for the existance of a cache dir (if XDG_CACHE_HOME is set). I'd argue that this is not needed. If the user has specified an XDG_CACHE_HOME that doesn't exist, we just mkdir_p() it rather than defaulting to DEFAULT_CACHE_LOCATION.

I don't understand here, because we need to test if XDG_CACHE_HOME is set or not. And if it is not, use DEFAULT_CACHE_LOCATION.

You can test if the variable is unset and/or empty the the code below - without trying to access the file:

const char *xdg_cache_home = getenv("XDG_CACHE_HOME");
if (!xdg_cache_home)
  printf("unset\n");
if (xdg_cache_home && !*xdg_cache_home)
  printf("empty string\n");  /* in other words "" */

So in our case I'd suggest:

if (!xdg_cache_home || !*xdg_cache_home) {
  /* Use CACHE_DEFAULT_LOCATION */
}

If C is not the language you normally code in I can explain further if helpful 😄

@johanmalm
Copy link
Collaborator

I'm happy to get rid of the following icon.c lines altogether. I actually think it's excessive logging which might be useful during development, but not for users.

if (nr_symlinks)
		fprintf(stderr, "info: created %d symlinks in %s\n", nr_symlinks, cache_icon_get_dir());

That would simplify things ever more smiley

I prefer to keep it in case we forgot something and removes it later.

👍

@tupo2
Copy link
Contributor Author

tupo2 commented Jun 25, 2022

So in our case I'd suggest:

if (!xdg_cache_home || !*xdg_cache_home) {
  /* Use CACHE_DEFAULT_LOCATION */
}

ok I didn't know about that, thanks.

@johanmalm
Copy link
Collaborator

johanmalm commented Jun 26, 2022

struct sbuf *cache_location; should be static struct sbuf *cache_location;. Otherwise it defaults to extern which makes it global. static keeps it within the translation unit (this file) which it much tidier.

cache_icon_get_dir() leaks memory if called more than once - which is the case with the patch.
Both xmalloc() and sbuf_init() allocate memory.
We should only allocate/free variable cache_location once.

I suggest doing the allocation in cache_init(), so in practical terms move all the stuff in cache_get_dir() and cache_icon_get_dir() to cache_init()

If you think it's tidier, it could be broken out into a separate function static void whatever() but it should only be called once (from cache_init())

cache_icon_get_dir() - which is called from icon.c should just be reduced to:

char *cache_icon_get_dir(void)
{
	return cache_location->buf;
}

There is no need to do anything else in there... the variable cache_location->buf is stored for the life of the jgmenu instance, so cache_icon_get_dir() is merely a "getter" if you're used to that terminology. It was common in object orientated programming a few years ago :)

@johanmalm johanmalm merged commit 9f6570d into jgmenu:master Jun 27, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Use XDG_CACHE_HOME environment variable
4 participants